package com.ztgf.pay.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.blue.system.AbstractException;
import com.blue.system.CodeException;
import com.blue.util.StringUtil;
import com.trz.netwk.api.ntc.*;
import com.trz.netwk.api.v6.ntc.NtcK5129Request;
import com.trz.netwk.api.v6.ntc.NtcK5224Request;
import com.trz.netwk.api.v6.ntc.NtcK5242Request;
import com.trz.netwk.api.v6.ntc.NtcK5246Request;
import com.trz.netwk.api.v6.vo.BusiBill;
import com.trz.netwk.api.v6.vo.Plan;
import com.trz.netwk.api.vo.ReFundBillInfo;
import com.trz.netwk.api.vo.SplitFundBillInfo;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.order.models.bo.OrderPayBO;
import com.ztgf.order.models.service.IOrderPayRelationService;
import com.ztgf.pay.async.IAsyncService;
import com.ztgf.pay.common.service.IPayCommonService;
import com.ztgf.pay.models.dto.*;
import com.ztgf.pay.models.service.*;
import com.ztgf.shopping.models.bo.shop.ShopAnnualFeeReturnBO;
import com.ztgf.shopping.models.bo.shop.ShopEarnestMoneyReturnBO;
import com.ztgf.shopping.models.service.shop.IShopAnnualFeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;

@DubboService
@Slf4j
public class ReceiveNoticeServiceImpl implements IReceiveNoticeService {

    @Autowired
    private IPayUserRechargeService payUserRechargeService;
    @Autowired
    private IPayOrderMotherService payOrderMotherService;
    @Autowired
    private IPayOrderService payOrderService;
    @Autowired
    private IPayOrderRepayService payOrderRepayService;
    @Autowired
    private IPayHttpLogService payHttpLogService;
    @Autowired
    private IAsyncService asyncService;
    @Autowired
    private IPayCommonService payCommonService;

    @Override
    public String doZjNotice(String ptncode, String trdcode, String message, String signature) {
        NoticeRequest noticeRequest = null;
        NtcBaseResponse noticeResponse = null;
        String result = "";
        //添加日志
        String name = "";
        String params = "";
        String returnValue = "";
        String businessStatus = "";
        String businessNotes = "";
        try {
            // 1 获得参数ptncode, trdcode, message和signature
            System.out.println("ptncode=" + ptncode);
            System.out.println("trdcode=" + trdcode);
            System.out.println("message=" + message);
            System.out.println("signature=" + signature);

            if (StringUtil.isEmpty(ptncode) || StringUtil.isEmpty(trdcode) || StringUtil.isEmpty(message) || StringUtil.isEmpty(signature)) {
                throw new CodeException("SDER04", "参数错误");
            }

            // 2 生成交易请求对象(验签)
            noticeRequest = new NoticeRequest(message, signature);
            log.error("-----------通知报文: " + noticeRequest.getPlainText());

            // 3 业务处理
            if ("T2008".equals(noticeRequest.getMsghd_trcd())) {
                // 3.3.5 入金结果通知[T2008]
                NtcT2008Request nr = new NtcT2008Request(noticeRequest.getDocument());

                name = "T2008";
                params = noticeRequest.getPlainText();
                businessStatus = nr.getState();
                businessNotes = "入金结果通知[T2008]";

                if("1".equals(nr.getState()) || "2".equals(nr.getState())){
                    PayUserRechargeDTO rechargeDTO = payUserRechargeService.selectById(nr.getSrl_srcptnsrl());
                    if("1".equals(nr.getState())){
                        rechargeDTO.setStatus(2);
                    } else if("2".equals(nr.getState())){
                        rechargeDTO.setStatus(3);
                    }
                    Wrapper wrapper = new EntityWrapper();
                    wrapper.eq("id", rechargeDTO.getId());
                    wrapper.eq("revision", rechargeDTO.getRevision());
                    PayUserRechargeDTO newRechargeDTO = new PayUserRechargeDTO();
                    newRechargeDTO.setId(rechargeDTO.getId());
                    newRechargeDTO.setStatus(rechargeDTO.getStatus());
                    newRechargeDTO.setRevision(rechargeDTO.getStatus() + 1);
                    if(!payUserRechargeService.update(newRechargeDTO, wrapper)){
                        throw new CodeException("SDER01", "入金结果通知[T2008]处理失败");
                    }
                    //回调
                    asyncService.notifyMargin(rechargeDTO);

                }


            }else if ("T4503".equals(noticeRequest.getMsghd_trcd())) {//网银支付通知
                System.out.println("====================4503notice=======================");
                NtcT4503Request nr = new NtcT4503Request(noticeRequest.getDocument());

                name = "T4503";
                params = noticeRequest.getPlainText();
                returnValue = "";
                businessStatus = nr.getState();
                businessNotes = "网银支付通知";

                PayOrderMotherDTO motherDTO = payOrderMotherService.selectById(nr.getSrl_ptnsrl());
                if(motherDTO != null){
                    int  status = 0;
                    if("1".equals(nr.getState())){
                        status = 2;

                    } else {
                        status = 3;
                    }

                    boolean isDo = true;
                    //查询子订单
                    Wrapper wrapper = new EntityWrapper();
                    wrapper.eq("mother_order_id", motherDTO.getId());
                    List<PayOrderDTO> orderDTOS = payOrderService.selectList(wrapper);
                    if(orderDTOS == null || orderDTOS.size() == 0){
                        throw new Exception();
                    }

                    //处理子订单
                    for (PayOrderDTO orderDTO : orderDTOS) {
                        orderDTO.setStatus(status);
                        orderDTO.setZjFailMsg(motherDTO.getZjFailMsg());
                        int revision = orderDTO.getRevision();
                        wrapper = new EntityWrapper();
                        wrapper.eq("id", orderDTO.getId());
                        wrapper.eq("revision", revision);

                        PayOrderDTO newOrderDTO = new PayOrderDTO();
                        newOrderDTO.setId(orderDTO.getId());
                        newOrderDTO.setStatus(status);
                        newOrderDTO.setRevision(revision + 1);
                        if(!payOrderService.update(newOrderDTO, wrapper)){
                            throw new CodeException("SDER01", "T4503 网银支付通知处理失败（处理子订单）");
                        }
                        if(status == 2){
                            //处理不可提现余额
                            payCommonService.saveNoWithdrawMoney(orderDTO.getPaymentUserId());
                        }
                        //回调
                        asyncService.notifyPayOrder(orderDTO);
                    }

                    motherDTO.setStatus(status);

                    wrapper = new EntityWrapper();
                    int revision = motherDTO.getRevision();
                    wrapper.eq("id", motherDTO.getId());
                    wrapper.eq("revision", revision);
                    motherDTO.setRevision(revision + 1);
                    if(!payOrderMotherService.update(motherDTO, wrapper)){
                        throw new CodeException("SDER01", "T4503 网银支付通知处理失败（处理母订单）");
                    }
                }

            }else if ("T4046".equals(noticeRequest.getMsghd_trcd())) {//分账类交易退款结果通知[T4046]
                NtcT4046Request nr = new NtcT4046Request(noticeRequest.getDocument());

                name = "T4046";
                params = noticeRequest.getPlainText();
                returnValue = "";
                businessStatus = nr.getState();
                businessNotes = "分账类交易退款结果通知[T4046]";

                PayOrderRepayDTO repayDTO = payOrderRepayService.selectById(nr.getSrl_ptnsrl());
                if(repayDTO != null){
                    payOrderRepayService.updateDTO(nr.getState(), repayDTO);
                }


            } else if ("T4042".equals(noticeRequest.getMsghd_trcd())) {
                // 3.9.2 退款结果通知[T4042]
                NtcT4042Request nr = new NtcT4042Request(noticeRequest.getDocument());

                name = "T4042";
                params = noticeRequest.getPlainText();
                returnValue = "";
                businessStatus = nr.getState();
                businessNotes = "余额退款结果通知[T4042]";

                PayOrderRepayDTO repayDTO = payOrderRepayService.selectById(nr.getSrl_ptnsrl());
                if(repayDTO != null){
                    payOrderRepayService.updateDTO(nr.getState(), repayDTO);
                }
            } else if ("T2020".equals(noticeRequest.getMsghd_trcd())) {
                // 3.9.2 退款结果通知[T4042]
                NtcT2020Request nr = new NtcT2020Request(noticeRequest.getDocument());

                name = "T2020";
                params = noticeRequest.getPlainText();
                returnValue = "";
                businessStatus = nr.getUbalsta();
                businessNotes = "提现结果通知[T2020]";

                PayUserRechargeDTO rechargeDTO = payUserRechargeService.selectById(nr.getSrl_ptnsrl());
                if("1".equals(nr.getUbalsta())){
                    rechargeDTO.setStatus(2);
                } else {
                    rechargeDTO.setStatus(3);
                }
                Wrapper wrapper = new EntityWrapper();
                wrapper.eq("id", rechargeDTO.getId());
                wrapper.eq("revision", rechargeDTO.getRevision());
                payUserRechargeService.update(rechargeDTO, wrapper);

            } else {
                throw new CodeException("MK2002", "暂不支持此交易");
            }

            // 4 处理响应报文参数
            noticeResponse = new NoticeResponse(noticeRequest);
            noticeResponse.setSrl_ptnsrl("" + System.currentTimeMillis()); // 合作方业务流水号
            // 000000 成功; 其它 失败
            noticeResponse.setMsghd_rspcode("000000");
            noticeResponse.setMsghd_rspmsg("业务办理成功");
        } catch (CodeException e) {
            // 4 处理响应报文参数
            noticeResponse = new NoticeResponse(noticeRequest);
            noticeResponse.setSrl_ptnsrl("" + System.currentTimeMillis()); // 合作方业务流水号
            // 000000 成功; 其它 失败
            noticeResponse.setMsghd_rspcode(e.getCode());
            noticeResponse.setMsghd_rspmsg(e.getMessage());
            e.printStackTrace();
        } catch (AbstractException e) {
            // 4 处理响应报文参数
            noticeResponse = new NoticeResponse(noticeRequest);
            noticeResponse.setSrl_ptnsrl("" + System.currentTimeMillis()); // 合作方业务流水号
            // 000000 成功; 其它 失败
            noticeResponse.setMsghd_rspcode("ERRRRR");
            noticeResponse.setMsghd_rspmsg(e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            // 4 处理响应报文参数
            noticeResponse = new NoticeResponse(noticeRequest);
            noticeResponse.setSrl_ptnsrl("" + System.currentTimeMillis()); // 合作方业务流水号
            // 000000 成功; 其它 失败
            noticeResponse.setMsghd_rspcode("ERRRRR");
            noticeResponse.setMsghd_rspmsg("业务办理失败");
            e.printStackTrace();
        } finally {
            // 5 响应智融平台
            try {
                if (null == noticeResponse) {
                    noticeResponse = new NoticeResponse(noticeRequest);
                    noticeResponse.setSrl_ptnsrl("" + System.currentTimeMillis()); // 合作方业务流水号
                    // 000000 成功; 其它 失败
                    noticeResponse.setMsghd_rspcode("ERRRRR");
                    noticeResponse.setMsghd_rspmsg("交易结果未知");
                }
                noticeResponse.process();
                System.out.println("响应报文: " + noticeResponse.getPlainText());
                returnValue = noticeResponse.getPlainText();
                result = noticeResponse.getMessage();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        try {
            PayHttpLogDTO logDTO = new PayHttpLogDTO();
            logDTO.setName(name);
            if(StrUtils.isEmpty(params)){
                params = message;
            }
            logDTO.setParams(params);
            logDTO.setReturnValue(returnValue);
            logDTO.setStatus(0);
            logDTO.setBusinessStatus(businessStatus);
            logDTO.setBusinessNotes(businessNotes);
            payHttpLogService.insert(logDTO);
        } catch (Exception e){
            log.error("doNotice insert log is error", e);
        }

        return result;
    }
}
